package com.sangmo.fts.process.inventory.service;

import com.sangmo.boot.framework.common.errors.ServiceException;
import com.sangmo.boot.framework.common.errors.StandardErrors;
import com.sangmo.boot.framework.common.session.UserSession;
import com.sangmo.boot.framework.common.utils.DateUtils;
import com.sangmo.boot.framework.data.filter.PageResult;
import com.sangmo.boot.framework.data.filter.PageSearch;
import com.sangmo.boot.framework.data.filter.ValueFilter;
import com.sangmo.boot.framework.data.idm.IdentityManager;
import com.sangmo.boot.framework.plugin.dataview.crud.service.DelegateViewService;
import com.sangmo.boot.framework.plugin.dataview.crud.service.ViewService;
import com.sangmo.fts.common.utils.RandomUtils;
import com.sangmo.fts.process.inventory.interfaces.IfLoanAuditRequest;
import com.sangmo.fts.process.inventory.model.IfLadingBill;
import com.sangmo.fts.process.inventory.model.IfLoan;
import com.sangmo.fts.process.inventory.model.IfWaybillItem;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

@Service
@Transactional
public class IfLoanService extends DelegateViewService<IfLoan> {

    @Autowired
    private IfLoanEntityService ifLoanEntityService;

    @Autowired
    private IdentityManager identityManager;

    @Autowired
    private IfWaybillService ifWaybillService;

    @Override
    protected ViewService<IfLoan> getEntityService() {
        return ifLoanEntityService;
    }

    public void audit(Long id, IfLoanAuditRequest request) {
        IfLoan loan = this.get(id);
        if (!IfLoan.States.PENDING.equals(loan.getState())) {
            throw new ServiceException(StandardErrors.CLIENT_ERROR.getStatus(), "error.ifLoan.audit.state.wrong");
        }
        loan.setAuditMind(request.getAuditMind());
        loan.setState(request.isPass()?IfLoan.States.CONFIRMED:IfLoan.States.REJECTED);
        loan.setIssueState(request.isPass()?IfLoan.IssueStates.PENDING:null);
        loan.setAuditBy((Long)UserSession.getUserInterface().getId());
        loan.setAuditTime(new Date());
        this.save(loan);
    }

    public void issue(Long id) {
        IfLoan loan = this.get(id);
        if (!IfLoan.States.CONFIRMED.equals(loan.getState())) {
            throw new ServiceException(StandardErrors.CLIENT_ERROR.getStatus(), "error.ifLoan.audit.state.wrong");
        }
        loan.setCode(identityManager.next("IfLoan.code2", 2)+DateUtils.format(new Date(), "yyyyMMdd")+identityManager.next("IfLoan.code4", 4));
        loan.setIssueState(IfLoan.IssueStates.COMPLETED);
        this.save(loan);
    }

   public PageResult<IfLoan> selection(PageSearch ps) {
       ps.getFilters().add(new ValueFilter("issueState", ValueFilter.OP_EQ, IfLoan.IssueStates.COMPLETED));
       ps.getFilters().add(new ValueFilter("settled", ValueFilter.OP_EQ, true));
       return ifLoanEntityService.search(ps);
   }

   public PageResult<IfWaybillItem> listGoodsItemsByPage(Long id, PageSearch ps) {
       IfLoan loan = this.get(id);
       return ifWaybillService.listItemsByPage(loan.getWaybillId(), ps);
   }

   public void settle(Long loanId, BigDecimal amount) {
       IfLoan loan = this.get(loanId);
       if (loan.getAmount().compareTo(amount) <= 0) {
           loan.setSettled(true);
           this.save(loan);
       }
   }
}
